package com.hcy.app.screen.cipher

import android.util.Base64
import org.bouncycastle.util.encoders.Hex
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

object CryptUtilForAes {
    private const val BLOCK_SIZE = 16 // 16字节的随机IV,AES密钥长度必须为128/192/256位(16/24/32字节),SM4密钥长度必须为128位(16字节)

    /**
     * 生成随机初始化向量(IV)，
     * IV-初始化向量，每次加密都应不同，不需要保密，通常与密文一起传输或存储。
     * 密信模块中会将其保存，保持数据库结构一致。
     * @return 16字节的随机IV
     */
    fun generateIV(): String{
        val iv = ByteArray(BLOCK_SIZE)
        SecureRandom().nextBytes(iv)
        return Hex.toHexString(iv) // 使用Hex编码
    }
    /**
     * 生成特定长度的随机字符串
     */
    fun generateKey(): String {
        val iv = ByteArray(BLOCK_SIZE)
        SecureRandom().nextBytes(iv)
        return Hex.toHexString(iv) // 使用Hex编码
    }

    fun generate(): Pair<String, String>{
        return Pair(generateKey(),generateIV())
    }


    /**
    * 加密字符串
    * @param keyHex 加密密码
    * @param plaintext 待加密的明文
    * @return Base64 编码的加密字符串
    */
    fun encrypt( plaintext: String,keyHex: String, ivHex: String): String {
        val keyBytes = Hex.decode(keyHex) // 解码Hex字符串得到原始字节
        val ivBytes = Hex.decode(ivHex)   // 解码Hex字符串得到原始字节

        val key = SecretKeySpec(keyBytes, "AES")
        val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
        val ivSpec = IvParameterSpec(ivBytes)
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec)
        val cipherText = cipher.doFinal(plaintext.toByteArray(charset("UTF-8")))
        return Hex.toHexString(cipherText)
    }

    /**
    * 解密字符串
    * @param ciphertextHex 密文14进制字符串
    * @param keyHex 解密密码（需与加密密码相同）
    * @return 解密后的原始字符串
    */
    fun decrypt( ciphertextHex: String,keyHex: String, ivHex: String): String {
        val keyBytes = Hex.decode(keyHex) // 解码Hex字符串得到原始字节
        val ivBytes = Hex.decode(ivHex)   // 解码Hex字符串得到原始字节

        val key = SecretKeySpec(keyBytes, "AES")
        val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
        val ivSpec = IvParameterSpec(ivBytes)
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec)
        val decryptedBytes = cipher.doFinal(Hex.decode(ciphertextHex))
        return Hex.toHexString(decryptedBytes)
    }

}